昨天我們講解了容器如何儲放資料,關於掛載的部分,只講了約定掛載,今天我們來講講有別於儲放在本機的 volume 掛載。
volume 是 docker 裡的一個儲存元件,有別於掛載,volume 是從 docker 內切出一塊獨立空間出來,提供容器使用,讓容器可以儲放資料。因此,容器被刪除,也不會影響到 volume。那這個被另外切出來的空間,也是要透過掛載,讓 volume 跟容器彼此連結。
既然如此,那代表 volume 也是要另外創造:
> docker volume create --name iThome_volume
iThome_volume
然後我們可以查看 volume 的清單:
> docker volume ls                                                                                              ✔  3.1.3   16:28:48
DRIVER    VOLUME NAME
local     iThome_volume
也可透過 inspect 查看 volume 的詳細資料:
> docker volume inspect iThome_volume                                                                           ✔  3.1.3   16:29:06
[
    {
        "CreatedAt": "2023-09-10T08:27:43Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/iThome_volume/_data",
        "Name": "iThome_volume",
        "Options": null,
        "Scope": "local"
    }
]
嘗試再建立另外一個 volume ,並看兩者的 Mountpoint :
iThome_volume:
"Mountpoint": "/var/lib/docker/volumes/iThome_volume/_data"
another_volume:
"Mountpoint": "/var/lib/docker/volumes/another_volume/_data"
由此可知, volume 是從 docker 裡去另外製造出來的。
這裡也是使用 --mount 或 -v ,但要注意的是 --mount 的 type 是 volume ,而不是 bind :
docker container run --name iThome --mount type=volume,source=iThome_volume,target="/usr/local/apache2/htdocs/" -p 8001:80 -d httpd
或
docker container run -v iThome_volume:/usr/local/apache2/htdocs/ -d httpd
然後我們 inspect 容器,可以看到容器 Mounts 的 source 就是剛剛我們 inspect volume 時的 Mountpoint 。
除了上述的建立 volume 的 create 以外,還有很多常用的指令,像是 ls 查看 volume 清單, inspect 查看特定 volume, rm 刪除 volume。用法跟容器的一樣。只是把 container 改成 volume
那我們來試著刪除剛剛 iThome 容器的 volume iThome_volume ,這時會發現他不給刪:
> docker volume rm iThome_volume
Error response from daemon: remove iThome_volume: volume is in use - [4671d716df2040b93ff740f8466bd80909af55196b33e8a407a93299b45b18a9]
錯誤訊息很明顯告訴我們, volume 使用中。這是一個很正常的機制。
如果想要刪除掉 volume ,就必須確保沒有容器在使用 volume 後才能刪除。
所謂的沒有容器在使用是指,使用該 volume 的容器,必須都被刪除了,已經沒有這些使用它的容器了,如果只是把容器 stop 或 kill,那仍然還是在使用著 volume ,一樣刪不掉 volume 。
講了這麼多,到底誰會用到 volume 呢? 只要是會產生資料的容器,就需要 volume 嗎? 其實未必。
用 Rails 舉例, Rails 專案的容器會有 Rails app 本身的容器,另外還會有與 Rails 串接的資料庫容器,兩種容器 ( 這裡只談簡配、不談 sidekiq, redis )。這裡會需要 volume 的只有資料庫容器,因為資料庫容器是負責資料儲放的容器。透過 Rails 產生的資料,會經過容器間的通訊,將資料傳遞給資料庫容器,所以需要將儲放資料的容器進行掛載,讓資料得以被保存。
讓我們來簡單整理一下今天的 Volume:
volume ,就無法刪除 volume
那容器就介紹到這邊,接下來我們要進入到也是很重要的映像檔 image 的世界了。